package sample.plugin;

/*
 * Copyright 2001-2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.ClassUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Settings;
import org.apache.maven.shared.utils.io.DirectoryScanner;
import org.apache.maven.shared.utils.io.FileUtils;
import org.apache.maven.shared.utils.io.IOUtil;
import org.apache.maven.shared.utils.io.ScanConductor.ScanAction;
import org.codehaus.classworlds.ClassRealm;
import org.codehaus.classworlds.ClassWorld;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLDecoder;
import java.util.List;

/**
 * Goal which touches a timestamp file.
 * http://www.onjava.com/pub/a/onjava/2005/01/26/classloading.html?page=3
 * @goal outputIsReport http://maven.apache.org/plugin-developers/
 * @phase test
 */
@Mojo(name = "outputIsReport")
public class MyMojo extends AbstractMojo {
	/**
	 * The Maven Project.
	 */
	@Component
	protected MavenProject project;

	/**
	 * Local Repository.
	 */
	@Parameter(defaultValue = "${localRepository}", readonly = true, required = true)
	protected ArtifactRepository localRepository;

	/**
	 * The Maven Settings.
	 */
	@Component
	private Settings settings;

	/**
	 * Location of the file.
	 * 
	 * @parameter expression="${project.build.directory}"
	 * @required
	 */
	@Parameter(defaultValue = "${project.build.directory}", readonly = true, required = true)
	private File outputDirectory;

	@Parameter(defaultValue = "${project.build.testOutputDirectory}", readonly = true, required = true)
	private File testOutputDirectory;

	@Parameter(defaultValue = "${project.build.testSourceDirectory}", readonly = true, required = true)
	private File testSourceDirectory;
	
	public void execute() throws MojoExecutionException {
		getLog().info("outputIsReport. ,I'm Robert");
		File f = outputDirectory;
		getLog().info("outputDirectory: " + outputDirectory);
		getLog().info("testOutputDirectory: " + testOutputDirectory);
		getLog().info("testSourceDirectory: " + testSourceDirectory);
		getLog().info("project: " + project);
		getLog().info("project: " + project.getFile());
		File files = project.getFile();
		getLog().info("project.getFile(): " +project.getFile().getAbsolutePath());
		getLog().info("localRepository: " + localRepository.getBasedir());

		
		if (settings != null) {
			getLog().info("settings: " + settings.getLocalRepository());
		}
		ClassWorld world = new ClassWorld();

		
		
		try {
			List<String> dependencies = project.getCompileDependencies();
			
			List collectedProjects = project.getCollectedProjects();
			
			getLog().info("collectedProjects: "+collectedProjects.size());
			
			ClassRealm containerRealm    = world.newRealm( "container" );
			ClassRealm logComponentRealm = world.newRealm( "logComponent" );
			
			 
			getLog().info(""+dependencies.size());
			
			for(String path : dependencies){
				getLog().info("dependencies: " + path);
			}
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} 
			 
//			try {
				String[] listFile =   FileUtils.getFilesFromExtension(testOutputDirectory.getAbsolutePath(), "class");
				
				getLog().info("testOutputDirectory size: " + listFile.length);
				
				//TODO 建議可以看org.apache.tools.ant.AntClassLoader 看是如何載入class			

				final	ClassLoader parentClassLoader = Thread.currentThread().getContextClassLoader();
				final String classPath = extractClasspath(parentClassLoader);
				getLog().info("classPath: "+classPath);
				
//				final URLClassLoader classLoader= new URLClassLoader(new URL[] { testOutputDirectory.toURL() }, parentClassLoader);	
				
				
//				for(String fileName : listFile){
//					getLog().info("fileName: " + fileName);
//					String className = StringUtils.substringAfterLast(fileName, testOutputDirectory.getAbsolutePath()+ File.separator).replace("/",".").replace(".class","");
//					getLog().info("className: " + className);
//					classLoader.loadClass(className);				
//				}
//			} catch (MalformedURLException e) {
//				getLog().error(e.getMessage() ,e );
//			} catch (ClassNotFoundException e) {
//				getLog().error(e.getMessage() ,e );
//			} 
			
			
		if (f != null && !f.exists()) {
			f.mkdirs();
		}

		File touch = new File(f, "touch.txt");

		FileWriter w = null;
		try {
			w = new FileWriter(touch);

			w.write("touch.txt");
		} catch (IOException e) {
			throw new MojoExecutionException("Error creating file " + touch, e);
		} finally {
			if (w != null) {
				try {
					w.close();
				} catch (IOException e) {
					// ignore
				}
			}
		}
	}
	private  static String extractClasspath(ClassLoader cl) {
		StringBuffer buf = new StringBuffer();
		String anotherCp = null;
		while (cl != null) {
			 
			if (cl instanceof URLClassLoader) {
				URL urls[] = ((URLClassLoader) cl).getURLs();
				for (int i = 0; i < urls.length; i++) {
					if (buf.length() > 0) {
						buf.append(File.pathSeparatorChar);
					}

					try {
						String decodedURL = URLDecoder.decode(urls[i].getFile()
								.toString(), "UTF-8");
						buf.append(decodedURL);
					} catch (UnsupportedEncodingException e) {
						e.printStackTrace();
						buf.append(urls[i].getFile().toString());
					}
				}
			}
			cl = cl.getParent();
		}
		if (anotherCp != null) {
			return anotherCp;
		} else {
			return buf.toString();
		}
	}
}
